package com.jmb.apiplatform.service.impl;

import com.jmb.apiplatform.exception.ValidException;
import com.jmb.apiplatform.mapper.ApiTestCacheParameterMapper;
import com.jmb.apiplatform.mapper.ApiTestCaseMapper;
import com.jmb.apiplatform.pojo.ApiTestCacheParameter;
import com.jmb.apiplatform.pojo.ApiTestCacheParameterTO;
import com.jmb.apiplatform.pojo.ApiTestCacheParameterVO;
import com.jmb.apiplatform.service.ApiTestCacheParameterService;
import com.jmb.apiplatform.util.ValidUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

/**
* @author jinbo
* @description 针对表【api_test_cache_parameter(此表是参数缓存，请求参数缓存，响应数据缓存)】的数据库操作Service实现
* @createDate 2025-02-06 15:53:57
*/


@Slf4j
@Service
public class ApiTestCacheParameterServiceImpl  implements ApiTestCacheParameterService{
    @Autowired
    private ApiTestCacheParameterMapper apiTestCacheParameterMapper;
    @Autowired
    private ApiTestCaseMapper apiTestCaseMapper;

    @Override
    public ApiTestCacheParameterVO findCacheParameterByName(String name) {
        if (name!=null){
            return apiTestCacheParameterMapper.selectCacheParameterByName(name);
        }else {
            return null;
        }
    }
    // 查询主键详情
    @Override
    public ApiTestCacheParameterVO findCacheParameterById(Integer processorId) {
        return apiTestCacheParameterMapper.selectCacheParameterById(processorId);
    }

    @Override
    public List<Integer> findCacheParameterByCaseId(Integer caseId) {
        return apiTestCacheParameterMapper.selectCacheParameterByCaseId(caseId);
    }

    @Override
    public List<ApiTestCacheParameterVO> checkCacheParameterName(Integer processorId, String name) {
        return apiTestCacheParameterMapper.checkCacheParameterName(processorId,name);
    }

    @Override
    public List<ApiTestCacheParameterVO> findCacheParameterList(ApiTestCacheParameterTO apiTestCacheParameterTO) {
        return apiTestCacheParameterMapper.checkCacheParameterList(apiTestCacheParameterTO);
    }

    @Transactional
    @Override
    public ApiTestCacheParameter saveApiTestCacheParameter(ApiTestCacheParameter apiTestCacheParameter) throws ValidException {
        try {
            this.check(apiTestCacheParameter);
        }catch (ValidException e){
            log.info("参数名称不符合需求");
            throw e;
        }
        Date date = new Date();
        apiTestCacheParameter.setCreatedTime(date);
        apiTestCacheParameter.setUpdateTime(date);
        // 检查缺省值
        Integer haveDefaultValue = apiTestCacheParameter.getHaveDefaultValue();
        String defaultValue = apiTestCacheParameter.getDefaultValue();
        if (haveDefaultValue==0){  // 0表示没有默认值，存在缺省值，不能为空
            if (defaultValue==null || defaultValue.isEmpty()){
                throw new ValidException("参数缺省值不能为空");
            }
        }else if (haveDefaultValue==1){ // 不存在缺省值，将值赋为null
            apiTestCacheParameter.setDefaultValue(null);
        }else{
            throw new ValidException("参数缺省值错误");
        }
        // 1.检查caseId是否为空
        Integer caseId = apiTestCacheParameter.getCaseId();
        if (caseId==null){
            log.error("新增数据缓存时，请求参数&响应数据用例编号为空");
            throw new ValidException("新增数据缓存时，数据缓存用例编号为空");
        }
        if (apiTestCacheParameterMapper.selectCacheParameterByCaseId(caseId)==null){
            log.error("新增数据缓存时，数据缓存用例编号不存在");
            throw new ValidException("数据缓存用例编号不存在");
        }
        // 2.检查name唯一性
        String name = apiTestCacheParameter.getName();
        if (findCacheParameterByName(name)!=null){
            log.info("新增数据缓存时，数据缓存参数名称为：{}",name);
            throw new ValidException("数据缓存参数名称重复");
        }
        apiTestCacheParameterMapper.insertCacheParameter(apiTestCacheParameter);
        return apiTestCacheParameter;
    }

    @Override
    public void editApiTestCacheParameter(ApiTestCacheParameter apiTestCacheParameter) throws ValidException {
        // 数据校验
        this.check(apiTestCacheParameter);
        apiTestCacheParameter.setUpdateTime(new Date());
        // 检查缺省值
        Integer haveDefaultValue = apiTestCacheParameter.getHaveDefaultValue();
        String defaultValue = apiTestCacheParameter.getDefaultValue();
        if (haveDefaultValue==0){ //存在缺省值，赋值不能为空
            if (defaultValue==null || defaultValue.isEmpty()){
                throw new ValidException("参数缺省值不能为空");
            }
        }else if (haveDefaultValue==1){ // 不存在缺省值，直接把值赋为null
            apiTestCacheParameter.setDefaultValue(null);
        }else {
            throw new ValidException("参数缺省值错误");
        }
        // 1.检查caseId合法性
        Integer caseId = apiTestCacheParameter.getCaseId();
        if (caseId==null){
            log.error("修改数据缓存时，请求参数&响应数据用例编号为空");
            throw new ValidException("修改数据缓存时，数据缓存用例编号为空");
        }
        if (apiTestCacheParameterMapper.selectCacheParameterByCaseId(caseId)==null){
            log.error("修改数据缓存时，数据缓存用例编号不存在,caseId={}",caseId);
            throw new ValidException("数据缓存用例编号不存在");
        }
        // 2. 检查name唯一性
        String name = apiTestCacheParameter.getName();
        Integer processorId = apiTestCacheParameter.getProcessorId();
        if (!checkCacheParameterName(processorId,name).isEmpty()){
            log.info("修改数据缓存时，数据缓存参数名称为：{}",name);
            throw new ValidException("数据缓存参数名称重复");
        }
        apiTestCacheParameterMapper.updateCacheParameter(apiTestCacheParameter);
    }

    /**
     * 根据id删除参数缓存
     * @param processorId 参数缓存id
     */
    @Override
    public void removeCacheParameterById(Integer processorId) {
        apiTestCacheParameterMapper.deleteCheckCacheParameterById(processorId);
    }

    /**
     * 根据caseId删除参数缓存
     * @param caseId 用例id
     */
    @Override
    public void removeCacheParameterByCaseId(Integer caseId) {
        apiTestCacheParameterMapper.deleteCheckCacheParameterByCaseId(caseId);

    }


    // 校验数据，是否以json&xpath类型的$和//开头
    public void check(ApiTestCacheParameter cacheParameter) throws ValidException{
        // 1. 数据校验
        Integer caseId = cacheParameter.getCaseId();
        ValidUtil.notNUll(caseId,"用例编号不能为空");
        String name = cacheParameter.getName();
        ValidUtil.notNUll(name,"参数名称不能为空");
        ValidUtil.notEmpty(name,"参数名称不能为空");
        ValidUtil.length(name,1,50,"参数名称不能超过50个字符");
        // 2.参数名称必须是字母数字下划线
        if (!name.matches("\\w+")){
            throw new ValidException("参数名称必须是字母数字下划线");
        }
        Integer type = cacheParameter.getType();
        ValidUtil.notNUll(type,"参数类型不能为空");
        ValidUtil.size(type,0,6,"参数类型只能是0~6");

        String expression = cacheParameter.getExpression();
        ValidUtil.notNUll(expression,"参数表达式不能为空");
        ValidUtil.notEmpty(expression,"参数表达式不能为空");
        ValidUtil.length(expression,1,50,"参数表达式不能超过50个字符");

        /**
         * 0 response-json
         * 1 response-html
         * 2 response-header
         * 3 request-header
         * 4 request-params
         * 5 request-data
         * 6 request-json
         * todo 0、5、6类型，需要校验是否是jsonPath 1 类型，需要校验是否是xpath 2、3、4类型直接保存
         */
        if (type==0){
            ValidUtil.isJsonPath(expression);
        }else if (type==1){
            ValidUtil.isXmlPath(expression);
        }else if (type>4 && type<=6){
            ValidUtil.isJsonPath(expression);
        }
    }
}




